//最后的需求是,要求我们应用 令牌的方法来将我们的用户的信息来进行保存起来;
/*
1.直接把字典转化成plist 的文件;
2.将字典转化成 JSON(文件来进行的保存)这个使用的越来越频繁
3.归档 和 解档
4.SQLite
*/
import UIKit
/// 用户界面模型
class UserAccount: NSObject,NSCoding {
    /// 用户是否登录标记
    class var userLogon: Bool {
        return sharedAccount != nil
    }
    //用于调用access_token，接口获取授权后的access token。
    var access_token : String?
    //access_token的生命周期，单位是秒数。 准确的数据类型是一个 '数值'
    var expires_in : NSTimeInterval = 0{
        didSet{
            expiresDate = NSDate(timeIntervalSinceNow: expires_in)
        }
    }
    //添加 过期的日期
    var expiresDate: NSDate?
    //当前授权用户的UID。
    var uid : String?
    //用户头像地址（大图），180×180像素
    var avatar_large : String?
    //友好显示名称
    var name : String?
    init(dict: [String : AnyObject]){
        super.init()
        setValuesForKeysWithDictionary(dict)
        //设置的全局的访问的点,token 和 用户的数据的加载;
        UserAccount.userAccout = self
    }
    //要求实现的不完全的key 中的,字典转模型的实现
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
    //对象信息的描述
    override var description: String{
        let properties = ["access_token","expires_in","uid","expiresDate"]
        return "\(dictionaryWithValuesForKeys(properties))"
        /*上面的返回的是: ["access_token": 2.00YjN6PGLM4qGB4fd4e2297diE4HaB, "uid": 5724453028, "expires_in": 157679999]   非常格式化的答应的输出  */
    }
    //MARK:-加载用户的信息(抽封的方法),用户登录成功以后,加载当前的个人的信息
    func loadUserInfo(finished:(error : NSError?) -> ()) {
        netWorkTools.sharedTool.loadUserInfo(uid!) { (result, error) -> () in
        if error != nil {
            //提示的是: error 是一定要传递的
            finished(error: error)
            return
            }
        //设置用户的信息(包括的是 用户名的昵称,还有是用户的头像)
        self.name = result!["name"] as? String
        self.avatar_large = result!["avatar_large"] as? String
        //保存用户的方法
        self.saveAccount()
        //完成回调
        finished(error: nil)
        }
    }
    
    //MARK:归档-解档的方法;
    ///保存归档文件的路径;
    static private let accountPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!+"/acount.plist"
    /// 保存用户信息
    func saveAccount(){
        NSKeyedArchiver.archiveRootObject(self, toFile: UserAccount.accountPath)
    }
    /**
    1.如果没有登录,返回的用户的信息就是 为 空;
    2.如果 token 过期,返回为 空;
    由于后续的网络的访问都需要依赖于 token ,每次的都要读取.
    如果每次都要读取的话,"解档" 就是性能的浪费需要从磁盘的(I/0),实际开发中,需要注意缓存 
    */
    /// 静态的用户帐号的属性
    private static var userAccout: UserAccount?
    class var sharedAccount: UserAccount? {
        //1.判断用户帐号是否存在;
        if userAccout == nil{
            //解档
            userAccout = NSKeyedUnarchiver.unarchiveObjectWithFile(accountPath) as? UserAccount
        }
        //2.判断日期;
        if let date = userAccout?.expiresDate where date.compare(NSDate()) == NSComparisonResult.OrderedAscending{
            //如果已经过期,就要清空帐号的记录
            userAccout = nil
        }
        return userAccout
    }
    /// 加载用户的信息
    //MARK:归档-解档 用户数据;
    /*
    归档: -> 保存,将自定义的对象转化成 二进制的数据保存到磁盘中;
    全部的保存下来,以 键值的方式来进行;
    
    解档: -> 解读,恢复 将二进制的数据从磁盘中恢复成自定义的对象;
    都是一些固定的写法,要求熟记的应用;
    */
    /// 归档的应用
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(access_token, forKey: "access_token")
        aCoder.encodeObject(expires_in, forKey: "expires_in")
        aCoder.encodeObject(expiresDate, forKey: "expiresDate")
        aCoder.encodeObject(uid, forKey: "uid")
    }
    /// 解档的应用
    required init?(coder aDecoder: NSCoder) {
        access_token = aDecoder.decodeObjectForKey("access_token") as? String
        expires_in = (aDecoder.decodeObjectForKey("expires_in") as? NSTimeInterval)!
        expiresDate = aDecoder.decodeObjectForKey("expiresDate") as? NSDate
        uid = aDecoder.decodeObjectForKey("uid") as? String
    }
}
